package com.foreveross.chameleon.user.plugin;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;

import com.baidu.tts.answer.auth.AuthInfo;
import com.baidu.tts.client.SpeechError;
import com.baidu.tts.client.SpeechSynthesizeBag;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;
import com.nancy.baiduyuyintest.R;
import com.foreveross.chameleon.utils.PropertiesUtil;
import com.google.gson.JsonArray;

import android.app.Activity;
import android.content.res.Resources;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.widget.Toast;

public class BDTTSPlugin extends CordovaPlugin implements SpeechSynthesizerListener{
	
	private String mSampleDirPath;
	private static final String SAMPLE_DIR_NAME = "baiduTTS";
    private static final String SPEECH_FEMALE_MODEL_NAME = "bd_etts_speech_female.dat";
    private static final String SPEECH_MALE_MODEL_NAME = "bd_etts_speech_male.dat";
    private static final String TEXT_MODEL_NAME = "bd_etts_text.dat";
    private static final String LICENSE_FILE_NAME = "temp_license";
    private static final String ENGLISH_SPEECH_FEMALE_MODEL_NAME = "bd_etts_speech_female_en.dat";
    private static final String ENGLISH_SPEECH_MALE_MODEL_NAME = "bd_etts_speech_male_en.dat";
    private static final String ENGLISH_TEXT_MODEL_NAME = "bd_etts_text_en.dat";
    
  //测试APP信息字段
    private static String APP_ID = "7641731";
    private static String API_KEY = "UDR6tvOvQef8Ed1pV9WEWueB";
    private static String API_SECRET = "001d7bf6cf7002352340fe7c4e64a2aa";
    
    
    private SpeechSynthesizer mSpeechSynthesizer;

    private Activity activity;
    private CallbackContext cbtx;
    List<SpeechSynthesizeBag> bags=null;
    
	@Override
	public boolean execute(String action, final JSONArray args,CallbackContext callbackContext) throws JSONException {

		cbtx=callbackContext;
		activity=this.cordova.getActivity();
		String tempAppId = PropertiesUtil.readProperties(this.cordova.getActivity(), R.raw.cube).getString("BaiduVoice_APP_ID", "");
		String tempApiKey= PropertiesUtil.readProperties(this.cordova.getActivity(), R.raw.cube).getString("BaiduVoice_API_KEY", "");
		String tempApiSecret=PropertiesUtil.readProperties(this.cordova.getActivity(), R.raw.cube).getString("BaiduVoice_API_SECRET", "");
		if(!(tempAppId.equals("")||tempApiKey.equals("") ||tempApiSecret.equals(""))){
			APP_ID=tempAppId;
			API_KEY=tempApiKey;
			API_SECRET=tempApiSecret;
		}
		if(action.equals("getTextToSynthesizer")){
			
			initialEnv();
			initialTts();
			JSONArray ja=args.getJSONArray(0);
			if(ja.getString(ja.length()-1).equals("YES")){
				bags=synthesizeBags(ja);
				speak(bags);
			}else{
				bags=synthesizeBags(ja);
				callbackContext.success();
			}
			
		}else if(action.equals("PlayVoice")){
			
			if(bags!=null){
				speak(bags);
			}else{
				cbtx.error("没有合成的语音数据");
			}
			
		}
		
		// TODO Auto-generated method stub
		return super.execute(action, args, callbackContext);
	}
	
	private void initialEnv() {
        if (mSampleDirPath == null) {
            String sdcardPath = Environment.getExternalStorageDirectory().toString();
            mSampleDirPath = sdcardPath + "/" + SAMPLE_DIR_NAME;
        }
        makeDir(mSampleDirPath);
        copyFromAssetsToSdcard(false, SPEECH_FEMALE_MODEL_NAME, mSampleDirPath + "/" + SPEECH_FEMALE_MODEL_NAME);
        copyFromAssetsToSdcard(false, SPEECH_MALE_MODEL_NAME, mSampleDirPath + "/" + SPEECH_MALE_MODEL_NAME);
        copyFromAssetsToSdcard(false, TEXT_MODEL_NAME, mSampleDirPath + "/" + TEXT_MODEL_NAME);
        copyFromAssetsToSdcard(false, LICENSE_FILE_NAME, mSampleDirPath + "/" + LICENSE_FILE_NAME);
        copyFromAssetsToSdcard(false, "english/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME, mSampleDirPath + "/"
                + ENGLISH_SPEECH_FEMALE_MODEL_NAME);
        copyFromAssetsToSdcard(false, "english/" + ENGLISH_SPEECH_MALE_MODEL_NAME, mSampleDirPath + "/"
                + ENGLISH_SPEECH_MALE_MODEL_NAME);
        copyFromAssetsToSdcard(false, "english/" + ENGLISH_TEXT_MODEL_NAME, mSampleDirPath + "/"
                + ENGLISH_TEXT_MODEL_NAME);
    }
	
	 private void makeDir(String dirPath) {
	        File file = new File(dirPath);
	        if (!file.exists()) {
	            file.mkdirs();
	        }
	 }
	 
	 /**
     * 将sample工程需要的资源文件拷贝到SD卡中使用（授权文件为临时授权文件，请注册正式授权）
     * 
     * @param isCover 是否覆盖已存在的目标文件
     * @param source
     * @param dest
     */
	 private void copyFromAssetsToSdcard(boolean isCover, String source, String dest) {
	        File file = new File(dest);
	        if (isCover || (!isCover && !file.exists())) {
	            InputStream is = null;
	            FileOutputStream fos = null;
	            try {
//	            	is = getResources().getAssets().open(source);
	                is = activity.getResources().getAssets().open(source);
	                String path = dest;
	                fos = new FileOutputStream(path);
	                byte[] buffer = new byte[1024];
	                int size = 0;
	                while ((size = is.read(buffer, 0, 1024)) >= 0) {
	                    fos.write(buffer, 0, size);
	                }
	            } catch (FileNotFoundException e) {
	                e.printStackTrace();
	            } catch (IOException e) {
	                e.printStackTrace();
	            } finally {
	                if (fos != null) {
	                    try {
	                        fos.close();
	                    } catch (IOException e) {
	                        e.printStackTrace();
	                    }
	                }
	                try {
	                    if (is != null) {
	                        is.close();
	                    }
	                } catch (IOException e) {
	                    e.printStackTrace();
	                }
	            }
	        }
	    }
	 
	 //--------------------------initialEnv到此结束-------------------------------

	 private void initialTts() {
	        this.mSpeechSynthesizer = SpeechSynthesizer.getInstance();
	        this.mSpeechSynthesizer.setContext(this.cordova.getActivity());
	        this.mSpeechSynthesizer.setSpeechSynthesizerListener(this);
	        // 文本模型文件路径 (离线引擎使用)
	        this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, mSampleDirPath + "/"
	                + TEXT_MODEL_NAME);
	        // 声学模型文件路径 (离线引擎使用)
	        this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, mSampleDirPath + "/"
	                + SPEECH_FEMALE_MODEL_NAME);
	        // 本地授权文件路径,如未设置将使用默认路径.设置临时授权文件路径，LICENCE_FILE_NAME请替换成临时授权文件的实际路径，仅在使用临时license文件时需要进行设置，如果在[应用管理]中开通了离线授权，不需要设置该参数，建议将该行代码删除（离线引擎）
	        this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_LICENCE_FILE, mSampleDirPath + "/"
	                + LICENSE_FILE_NAME);
	        // 请替换为语音开发者平台上注册应用得到的App ID (离线授权)
	        this.mSpeechSynthesizer.setAppId(APP_ID);
	        // 请替换为语音开发者平台注册应用得到的apikey和secretkey (在线授权)
	        this.mSpeechSynthesizer.setApiKey(API_KEY,API_SECRET);
	        // 授权检测接口
	        AuthInfo authInfo = this.mSpeechSynthesizer.auth(TtsMode.MIX);
	        if (authInfo.isSuccess()) {
	        	Log.w("toprint", "auth success");
	            this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, SpeechSynthesizer.SPEAKER_FEMALE);
	            mSpeechSynthesizer.initTts(TtsMode.MIX);
	            int result =
	                    mSpeechSynthesizer.loadEnglishModel(mSampleDirPath + "/" + ENGLISH_TEXT_MODEL_NAME, mSampleDirPath
	                            + "/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME);
	            Log.w("toprint", "loadEnglishModel result=" + result);
	        } else {
	            String errorMsg = authInfo.getTtsError().getDetailMessage();
	            Log.w("toprint", "auth failed errorMsg=" + errorMsg);
	            cbtx.error("auth failed errorMsg=" + errorMsg);
	            
	        }
	    }
	 

		 // 读 
		 private void speak(List<SpeechSynthesizeBag> bags){
			 int result = this.mSpeechSynthesizer.batchSpeak(bags);
		    if (result < 0) {
		    	cbtx.error("error,please look up error code in doc or URL:http://yuyin.baidu.com/docs/tts/122 ");
		    Log.d("toprint","error,please look up error code in doc or URL:http://yuyin.baidu.com/docs/tts/122 ");
		    }else{
		    	cbtx.success();
		    }
		}
		
		 //批量合成
		private List<SpeechSynthesizeBag> synthesizeBags(JSONArray ja) throws JSONException {
			int len=0;
			if(ja.getString(ja.length()-1).equals("YES")||ja.getString(ja.length()-1).equals("NO")){
				len=ja.length()-1;
			}else{
				len=ja.length();
			}
			Log.d("len",Integer.toString(len));
			 List<SpeechSynthesizeBag> bags = new ArrayList<SpeechSynthesizeBag>();
			    for(int i=0;i<len;i++){
			    	bags.add(getSpeechSynthesizeBag(ja.getString(i), Integer.toString(i)));
			    	Log.d("arr", ja.getString(i));
			} 
			return bags;
		}
		
		private SpeechSynthesizeBag getSpeechSynthesizeBag(String text, String utteranceId) {
		    SpeechSynthesizeBag speechSynthesizeBag = new SpeechSynthesizeBag();
		    speechSynthesizeBag.setText(text);
		    speechSynthesizeBag.setUtteranceId(utteranceId);
		    return speechSynthesizeBag;
		}
		
		@Override
		public void onDestroy() {
			bags=null;
			 this.mSpeechSynthesizer.release();
			// TODO Auto-generated method stub
			super.onDestroy();
		}
		
		@Override
		public void onPause(boolean multitasking) {
			// TODO Auto-generated method stub
			this.mSpeechSynthesizer.pause();
			super.onPause(multitasking);
		}
		
		@Override
		public void onResume(boolean multitasking) {
			// TODO Auto-generated method stub
			this.mSpeechSynthesizer.resume();
			super.onResume(multitasking);
		}
		
		@Override
		public void onStart() {
			// TODO Auto-generated method stub
			super.onStart();
		}
		
		@Override
		public void onStop() {
			// TODO Auto-generated method stub
			this.mSpeechSynthesizer.stop();
			super.onStop();
		}
		
		@Override
		public void onError(String utteranceId, SpeechError error) {
		Log.w("toprint","onError error=" + "(" + error.code + ")" + error.description + "--utteranceId=" + utteranceId);;
		cbtx.error("onError error=" + "(" + error.code + ")" + error.description + "--utteranceId=" + utteranceId);
		// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onSpeechFinish(String utteranceId) {
			
			Log.w("toprint", "onSpeechFinish utteranceId=" + utteranceId);
		// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onSpeechProgressChanged(String utteranceId, int arg1) {
			
			Log.w("toprint", "onSpeechStart utteranceId=" + utteranceId);
		// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onSpeechStart(String utteranceId) {
			Log.w("toprint", "onSpeechStart utteranceId=" + utteranceId);
		// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onSynthesizeDataArrived(String arg0, byte[] arg1, int arg2) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onSynthesizeFinish(String arg0) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onSynthesizeStart(String arg0) {
			// TODO Auto-generated method stub
			
		}

}
